package com.engine.salary.service.impl;

import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.taxagent.param.TaxAgentEmpSaveParam;
import com.engine.salary.entity.taxagent.po.TaxAgentEmpChangePO;
import com.engine.salary.entity.taxagent.po.TaxAgentEmpPO;
import com.engine.salary.enums.datacollection.DataCollectionEmployeeTypeEnum;
import com.engine.salary.enums.datacollection.UseEmployeeTypeEnum;
import com.engine.salary.enums.taxagent.TaxAgentEmpChangeModuleEnum;
import com.engine.salary.enums.taxagent.TaxAgentEmpChangeTypeEnum;
import com.engine.salary.mapper.taxagent.TaxAgentEmpMapper;
import com.engine.salary.service.TaxAgentEmpChangeService;
import com.engine.salary.service.TaxAgentEmpService;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.db.MapperProxyFactory;
import com.google.common.collect.Lists;
import com.engine.salary.util.db.IdGenerator;
import org.apache.commons.collections4.CollectionUtils;
import weaver.hrm.User;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 个税扣缴义务人管理范围的人员
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
public class TaxAgentEmpServiceImpl extends Service implements TaxAgentEmpService {


    private TaxAgentEmpMapper getTaxAgentEmpMapper() {
        return MapperProxyFactory.getProxy(TaxAgentEmpMapper.class);
    }

    public TaxAgentEmpChangeService getTaxAgentEmpChangeService(User user) {
        return ServiceUtil.getService(TaxAgentEmpChangeServiceImpl.class, user);
    }

    @Override
    public void deleteByTaxAgentIds(Collection<Long> taxAgentIds) {
        if (CollectionUtils.isEmpty(taxAgentIds)) {
            return;
        }
        List<TaxAgentEmpPO> taxAgentEmpList = getTaxAgentEmpMapper().listSome(TaxAgentEmpPO.builder().taxAgentIds(taxAgentIds).build());
        if (CollectionUtils.isEmpty(taxAgentEmpList)) {
            return;
        }
        List<Long> idList = taxAgentEmpList.stream().map(TaxAgentEmpPO::getId).collect(Collectors.toList());

        List<List<Long>> partition = Lists.partition(idList, 500);
        partition.forEach(getTaxAgentEmpMapper()::deleteByIds);
    }

    @Override
    public List<TaxAgentEmpPO> listByTaxAgentIds(List<Long> taxAgentIds, UseEmployeeTypeEnum type) {
        if (CollectionUtils.isEmpty(taxAgentIds)) {
            return Lists.newArrayList();
        }
        TaxAgentEmpPO param = TaxAgentEmpPO.builder().taxAgentIds(taxAgentIds).build();
        if (type == UseEmployeeTypeEnum.ORG) {
            param.setEmployeeType(DataCollectionEmployeeTypeEnum.ORGANIZATION.getValue());
        }

        if (type == UseEmployeeTypeEnum.EXT) {
            param.setEmployeeType(DataCollectionEmployeeTypeEnum.EXT_EMPLOYEE.getValue());
        }

        return getTaxAgentEmpMapper().listSome(param);
    }

    @Override
    public void syncTaxAgentEmployee(List<TaxAgentEmpSaveParam> taxAgentEmpSaveParamList, Long currentEmployeeId) {
        if (CollectionUtils.isEmpty(taxAgentEmpSaveParamList)) {
            return;
        }
        List<Long> taxAgentIds = taxAgentEmpSaveParamList.stream().map(TaxAgentEmpSaveParam::getTaxAgentId).collect(Collectors.toList());
        List<TaxAgentEmpPO> taxAgentEmployeeExistList = this.listByTaxAgentIds(taxAgentIds, UseEmployeeTypeEnum.ORG);
        Date now = new Date();
        // 关联表
        List<TaxAgentEmpPO> taxAgentEmployeeAddList = Lists.newArrayList();
        List<Long> taxAgentEmployeeDelIds = Lists.newArrayList();
        // 增量表
        List<TaxAgentEmpChangePO> taxAgentEmpChangeList = Lists.newArrayList();

        taxAgentEmpSaveParamList.forEach(saveParam -> {
            List<TaxAgentEmpPO> existList = taxAgentEmployeeExistList.stream().filter(f -> f.getTaxAgentId().equals(saveParam.getTaxAgentId())).collect(Collectors.toList());
            Map<String, TaxAgentEmpPO> taxAgentEmployeeMap = SalaryEntityUtil.convert2Map(existList, e -> e.getTaxAgentId() + "-" + e.getEmployeeId());
            for (DataCollectionEmployee se : saveParam.getSalaryEmployeeList()) {
                String key = saveParam.getTaxAgentId() + "-" + se.getEmployeeId();
                // 本地有的不动
                if (taxAgentEmployeeMap.containsKey(key)) {
                    taxAgentEmployeeMap.remove(key);
                    continue;
                }
                taxAgentEmployeeAddList.add(TaxAgentEmpPO.builder()
                        .id(IdGenerator.generate())
                        .taxAgentId(saveParam.getTaxAgentId())
                        .employeeId(se.getEmployeeId())
                        .employeeName(se.getUsername())
                        .creator(currentEmployeeId)
                        .createTime(now)
                        .updateTime(now)
                        .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
                        .deleteType(0)
                        .build());

                Arrays.stream(TaxAgentEmpChangeModuleEnum.values()).forEach(e -> {
                    taxAgentEmpChangeList.add(TaxAgentEmpChangePO.builder()
                            .id(IdGenerator.generate())
                            .taxAgentId(saveParam.getTaxAgentId())
                            .employeeId(se.getEmployeeId())
                            .employeeName(se.getUsername())
                            .changeType(TaxAgentEmpChangeTypeEnum.ADD.getValue())
                            .moduleType(e.getValue())
                            .creator(currentEmployeeId)
                            .createTime(now)
                            .updateTime(now)
                            .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
                            .deleteType(0)
                            .build());
                });

            }
            //遍历剩余的就是删除的
            for (String key : taxAgentEmployeeMap.keySet()) {
                TaxAgentEmpPO value = taxAgentEmployeeMap.get(key);
                taxAgentEmployeeDelIds.add(value.getId());

                Arrays.stream(TaxAgentEmpChangeModuleEnum.values()).forEach(e -> {
                    taxAgentEmpChangeList.add(TaxAgentEmpChangePO.builder()
                            .id(IdGenerator.generate())
                            .taxAgentId(saveParam.getTaxAgentId())
                            .employeeId(value.getEmployeeId())
                            .employeeName(value.getEmployeeName())
                            .changeType(TaxAgentEmpChangeTypeEnum.DEL.getValue())
                            .moduleType(e.getValue())
                            .creator(currentEmployeeId)
                            .createTime(now)
                            .updateTime(now)
                            .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
                            .deleteType(0)
                            .build());
                });
            }
        });

        // 关联表====================================================
        // 新增
        if (CollectionUtils.isNotEmpty(taxAgentEmployeeAddList)) {
            List<List<TaxAgentEmpPO>> partition = Lists.partition(taxAgentEmployeeAddList, 50);
            partition.forEach(getTaxAgentEmpMapper()::batchInsert);
        }
        // 删除
        if (CollectionUtils.isNotEmpty(taxAgentEmployeeDelIds)) {
            List<List<Long>> partition = Lists.partition(taxAgentEmployeeDelIds, 100);
            partition.forEach(getTaxAgentEmpMapper()::deleteByIds);
        }
        // 增量表====================================================
        if (CollectionUtils.isNotEmpty(taxAgentEmpChangeList)) {
            getTaxAgentEmpChangeService(user).batchInsert(taxAgentEmpChangeList);
        }
    }

    @Override
    public void syncTaxAgentExtEmployee(List<TaxAgentEmpSaveParam> taxAgentEmpSaveParamList, Long currentEmployeeId) {
        if (CollectionUtils.isEmpty(taxAgentEmpSaveParamList)) {
            return;
        }
        List<Long> taxAgentIds = taxAgentEmpSaveParamList.stream().map(TaxAgentEmpSaveParam::getTaxAgentId).collect(Collectors.toList());
        List<TaxAgentEmpPO> taxAgentEmployeeExistList = this.listByTaxAgentIds(taxAgentIds, UseEmployeeTypeEnum.EXT);
        Date now = new Date();
        // 关联表
        List<TaxAgentEmpPO> taxAgentEmployeeAddList = Lists.newArrayList();
        List<Long> taxAgentEmployeeDelIds = Lists.newArrayList();
        // 增量表
        List<TaxAgentEmpChangePO> taxAgentEmpChangeList = Lists.newArrayList();

        taxAgentEmpSaveParamList.forEach(saveParam -> {
            List<TaxAgentEmpPO> existList = taxAgentEmployeeExistList.stream().filter(f -> f.getTaxAgentId().equals(saveParam.getTaxAgentId())).collect(Collectors.toList());
            Map<String, TaxAgentEmpPO> taxAgentEmployeeMap = SalaryEntityUtil.convert2Map(existList, e -> e.getTaxAgentId() + "-" + e.getEmployeeId());
            for (DataCollectionEmployee se : saveParam.getSalaryEmployeeList()) {
                String key = saveParam.getTaxAgentId() + "-" + se.getEmployeeId();
                // 本地有的不动
                if (taxAgentEmployeeMap.containsKey(key)) {
                    taxAgentEmployeeMap.remove(key);
                    continue;
                }
                taxAgentEmployeeAddList.add(TaxAgentEmpPO.builder()
                        .id(IdGenerator.generate())
                        .taxAgentId(saveParam.getTaxAgentId())
                        .employeeId(se.getEmployeeId())
                        .employeeName(se.getUsername())
                        .employeeType(DataCollectionEmployeeTypeEnum.EXT_EMPLOYEE.getValue())
                        .creator(currentEmployeeId)
                        .createTime(now)
                        .updateTime(now)
                        .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
                        .deleteType(0)
                        .build());

                Arrays.stream(TaxAgentEmpChangeModuleEnum.values()).forEach(e -> {
                    taxAgentEmpChangeList.add(TaxAgentEmpChangePO.builder()
                            .id(IdGenerator.generate())
                            .taxAgentId(saveParam.getTaxAgentId())
                            .employeeId(se.getEmployeeId())
                            .employeeName(se.getUsername())
                            .changeType(TaxAgentEmpChangeTypeEnum.ADD.getValue())
                            .moduleType(e.getValue())
                            .employeeType(DataCollectionEmployeeTypeEnum.EXT_EMPLOYEE.getValue())
                            .creator(currentEmployeeId)
                            .createTime(now)
                            .updateTime(now)
                            .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
                            .deleteType(0)
                            .build());
                });

            }
            //遍历剩余的就是删除的
            for (String key : taxAgentEmployeeMap.keySet()) {
                TaxAgentEmpPO value = taxAgentEmployeeMap.get(key);
                taxAgentEmployeeDelIds.add(value.getId());

                Arrays.stream(TaxAgentEmpChangeModuleEnum.values()).forEach(e -> {
                    taxAgentEmpChangeList.add(TaxAgentEmpChangePO.builder()
                            .id(IdGenerator.generate())
                            .taxAgentId(saveParam.getTaxAgentId())
                            .employeeId(value.getEmployeeId())
                            .employeeName(value.getEmployeeName())
                            .changeType(TaxAgentEmpChangeTypeEnum.DEL.getValue())
                            .moduleType(e.getValue())
                            .employeeType(DataCollectionEmployeeTypeEnum.EXT_EMPLOYEE.getValue())
                            .creator(currentEmployeeId)
                            .createTime(now)
                            .updateTime(now)
                            .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
                            .deleteType(0)
                            .build());
                });
            }
        });

        // 关联表====================================================
        // 新增
        if (CollectionUtils.isNotEmpty(taxAgentEmployeeAddList)) {
            List<List<TaxAgentEmpPO>> partition = Lists.partition(taxAgentEmployeeAddList, 50);
            partition.forEach(getTaxAgentEmpMapper()::batchInsert);
        }
        // 删除
        if (CollectionUtils.isNotEmpty(taxAgentEmployeeDelIds)) {
            List<List<Long>> partition = Lists.partition(taxAgentEmployeeDelIds, 100);
            partition.forEach(getTaxAgentEmpMapper()::deleteByIds);
        }
        // 增量表====================================================
        if (CollectionUtils.isNotEmpty(taxAgentEmpChangeList)) {
            getTaxAgentEmpChangeService(user).batchInsert(taxAgentEmpChangeList);
        }
    }

}
